/**
 * 
 */
package ar.edu.utn.frsf.cidisi.ginet.generation.upcolbpip2cginet.elementstemplate;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;
import org.pnml.tools.epnk.pnmlcoremodel.AnnotationGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.ArcGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.Coordinate;
import org.pnml.tools.epnk.pnmlcoremodel.Name;
import org.pnml.tools.epnk.pnmlcoremodel.Node;
import org.pnml.tools.epnk.pnmlcoremodel.NodeGraphics;
import org.pnml.tools.epnk.pnmlcoremodel.PlaceNode;
import org.pnml.tools.epnk.pnmlcoremodel.PnmlcoremodelFactory;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.Declaration;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.HLAnnotation;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.HlpngdefinitionFactory;
import org.pnml.tools.epnk.pntypes.hlpng.pntd.hlpngdefinition.Type;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.MultiSetSort;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.NamedSort;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Sort;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.TermsFactory;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.UserSort;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Variable;
import org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.VariableDecl;

import ar.edu.utn.frsf.cidisi.ginet.abstractginet.AbstractGINet;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.AbstractginetFactory;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Arc;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Page;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Place;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.RefPlace;
import ar.edu.utn.frsf.cidisi.ginet.abstractginet.Transition;
import ar.edu.utn.frsf.cidisi.ginet.generation.upcolbpip2cginet.managers.PageGiNetCreator;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.BusinessMessage;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionPath;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.InteractionProtocolElement;
import ar.edu.utn.frsf.cidisi.upcolbpip.interactionprotocols.Termination;

/**
 * @author Neri
 * 
 */
public abstract class ChoreographyStructure {
	
	protected int pos;

	protected AbstractGINet abstractGinet = AbstractginetFactory.eINSTANCE
			.createAbstractGINet();
	
	protected Page abstractPage;

	protected EList<NamedSort> namedSorts;
	
	protected EList<VariableDecl> variableDecls;
	
	protected EList<InteractionProtocolElement> elementsIP;
	
	static protected Map<Integer, Float> columns = new HashMap<Integer, Float>();
	
	static protected Map<Integer, Float> rows = new HashMap<Integer, Float>();
	
	public Page getPage(){
		return this.abstractPage;
	}
	
	 // Static constructor
	  static {			
			//set columns
			rows.put(1,(float) 115);
			rows.put(2,(float) 230);
			rows.put(3,(float) 345);
			rows.put(4,(float) 460);
			rows.put(5,(float) 575);
			rows.put(6,(float) 690);
			rows.put(7,(float) 805);
			rows.put(8,(float) 920);
			rows.put(9,(float) 1035);
			rows.put(10,(float) 1150);
			rows.put(11,(float) 1265);
			
			//set rows
			columns.put(1, (float) 55);
			columns.put(2, (float) 140);
			columns.put(3, (float) 230);
			columns.put(4, (float) 320);
			columns.put(5, (float) 410);
			columns.put(6, (float) 500);
			columns.put(7, (float) 590);
			columns.put(8, (float) 680);
			columns.put(9, (float) 770);
			columns.put(10, (float) 860);
			columns.put(11, (float) 950);
	  }
	
	public ChoreographyStructure(){
		this.abstractPage = AbstractginetFactory.eINSTANCE.createPage();
		
		this.namedSorts = new BasicEList<NamedSort>();
		
		this.variableDecls = new BasicEList<VariableDecl>();
	}

	public Place createPlace(String id,
			int xPosition, int yPosition, String name, float nameX,
			float nameY, VariableDecl typePlace, float typeX, float typeY,
			boolean isInput, String parallelCardinality) {
		Place place = AbstractginetFactory.eINSTANCE.createPlace();

		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;

		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();

		coordinate.setX(40);
		coordinate.setY(40);

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(columns.get(xPosition));
		coordinate1.setY(rows.get(yPosition));

		graphics.setPosition(coordinate1);

		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		nameLabel.setText(name);

		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();

		coordinate2.setX(nameX);
		coordinate2.setY(nameY);

		graphicsName.setOffset(coordinate2);

		Type type = HlpngdefinitionFactory.eINSTANCE.createType();
		
		MultiSetSort multisort = (MultiSetSort) typePlace.getSort();

		type.setStructure(multisort.getBasis().clone());
		type.setText(((UserSort)multisort.getBasis()).getName());
		
		Coordinate coordinate3 = pnmlcoremodelFactory.createCoordinate();

		coordinate3.setX(typeX);
		coordinate3.setY(typeY);

		graphicsName.setOffset(coordinate3);

		type.setGraphics(graphicsName);

		place.setName(nameLabel);

		place.setGraphics(graphics);

		place.setType(type);
		
		place.setId(id);
		
		place.setParallelCardinality(parallelCardinality);
		
		if(isInput){
			place.setInput(isInput);
			place.setOutput(!isInput);
		}else{
			place.setInput(!isInput);
			place.setOutput(isInput);
		}

		return place;
	}
	
	public Place createPlace(String id,
			float xPosition, float yPosition, String name, float nameX,
			float nameY, VariableDecl typePlace, float typeX, float typeY,
			boolean isInput, String parallelCardinality) {
		Place place = AbstractginetFactory.eINSTANCE.createPlace();

		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;

		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();

		coordinate.setX(40);
		coordinate.setY(40);

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(xPosition);
		coordinate1.setY(yPosition);

		graphics.setPosition(coordinate1);

		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		nameLabel.setText(name);

		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();

		coordinate2.setX(nameX);
		coordinate2.setY(nameY);

		graphicsName.setOffset(coordinate2);

		Type type = HlpngdefinitionFactory.eINSTANCE.createType();
		
		MultiSetSort multisort = (MultiSetSort) typePlace.getSort();

		type.setStructure(multisort.getBasis().clone());
		type.setText(((UserSort)multisort.getBasis()).getName());
		
		Coordinate coordinate3 = pnmlcoremodelFactory.createCoordinate();

		coordinate3.setX(typeX);
		coordinate3.setY(typeY);

		graphicsName.setOffset(coordinate3);

		type.setGraphics(graphicsName);

		place.setName(nameLabel);

		place.setGraphics(graphics);

		place.setType(type);
		
		place.setId(id);
		
		place.setParallelCardinality(parallelCardinality);
		
		if(isInput){
			place.setInput(isInput);
			place.setOutput(!isInput);
		}else{
			place.setInput(!isInput);
			place.setOutput(isInput);
		}

		return place;
	}
	
	protected Transition createTransition(String id,
			int xPosition, int yPosition, String name, float nameX,
			float nameY, String parallelCardinality, String sequentialCardinality, Page refPage){
		Transition transition = AbstractginetFactory.eINSTANCE.createTransition();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();

		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		coordinate.setX(nameX);
		coordinate.setY(nameY);
		
		graphicsName.setOffset(coordinate);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);

		coordinate.setX(columns.get(xPosition));
		coordinate.setY(rows.get(yPosition));

		graphics.setPosition(coordinate);
		
		transition.setGraphics(graphics);
		transition.setId(id);		
		transition.setName(nameLabel);
		transition.setParallelCardinality(parallelCardinality);
		transition.setSequentialCardinality(sequentialCardinality);
		transition.setRefPage(refPage);
		
		return transition;
		
	}

	protected Transition createTransition(String id,
			float xPosition, float yPosition, String name, float nameX,
			float nameY, String parallelCardinality, String sequentialCardinality, Page refPage){
		Transition transition = AbstractginetFactory.eINSTANCE.createTransition();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();

		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		coordinate.setX(nameX);
		coordinate.setY(nameY);
		
		graphicsName.setOffset(coordinate);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);

		coordinate.setX(xPosition);
		coordinate.setY(yPosition);

		graphics.setPosition(coordinate);
		
		transition.setGraphics(graphics);
		transition.setId(id);		
		transition.setName(nameLabel);
		transition.setParallelCardinality(parallelCardinality);
		transition.setSequentialCardinality(sequentialCardinality);
		transition.setRefPage(refPage);
		
		return transition;
		
	}
	
	protected Arc createArc(String id,  VariableDecl var, float nameX,
			float nameY, Node source, Node target){
		
		Arc arc = AbstractginetFactory.eINSTANCE.createArc();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(var.getName());
		nameLabel.setGraphics(graphicsName);
		
		HLAnnotation annotation = HlpngdefinitionFactory.eINSTANCE.createHLAnnotation();
		AnnotationGraphics labelPos = PnmlcoremodelFactory.eINSTANCE.createAnnotationGraphics();
		Coordinate offset = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		offset.setX(0);
		offset.setY(30);
		labelPos.setOffset(offset);
		annotation.setGraphics(labelPos);
		annotation.setText(var.getName());
		
		Variable variable = TermsFactory.eINSTANCE.createVariable();
		
		variable.setRefvariable(var);
		annotation.setStructure(variable);


		arc.setId(id);
		arc.setName(nameLabel);
		arc.setSource(source);
		arc.setTarget(target);
		arc.setHlinscription(annotation);
		
		return arc;	
	}
	
	protected Arc createArc(String id,  VariableDecl var,String name, float nameX,
			float nameY, Node source, Node target){
		
		Arc arc = AbstractginetFactory.eINSTANCE.createArc();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		HLAnnotation annotation = HlpngdefinitionFactory.eINSTANCE.createHLAnnotation();
		AnnotationGraphics labelPos = PnmlcoremodelFactory.eINSTANCE.createAnnotationGraphics();
		Coordinate offset = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		offset.setX(0);
		offset.setY(30);
		labelPos.setOffset(offset);
		annotation.setGraphics(labelPos);
		annotation.setText(name);
		
		Variable variable = TermsFactory.eINSTANCE.createVariable();
		
		variable.setRefvariable(var);
		annotation.setStructure(variable);


		arc.setId(id);
		arc.setName(nameLabel);
		arc.setSource(source);
		arc.setTarget(target);
		arc.setHlinscription(annotation);
		
		return arc;	
	}
	
	protected Arc createArc(String id,
			float xPosition, float yPosition, float xPosition1, float yPosition1, VariableDecl var, float nameX,
			float nameY, Node source, Node target){
		
		Arc arc = AbstractginetFactory.eINSTANCE.createArc();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		ArcGraphics graphics = pnmlcoremodelFactory.createArcGraphics();

		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(xPosition);
		coordinate1.setY(yPosition);
		
		graphics.getPosition().add(coordinate1);
		
		Coordinate coordinate3 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate3.setX(xPosition);
		coordinate3.setY(yPosition);
		
		graphics.getPosition().add(coordinate3);
		
		Coordinate coordinate4 = pnmlcoremodelFactory.createCoordinate();

		coordinate4.setX(xPosition1);
		coordinate4.setY(yPosition1);
		
		graphics.getPosition().add(coordinate4);
		
		Coordinate coordinate5 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate5.setX(xPosition1);
		coordinate5.setY(yPosition1);
		
		graphics.getPosition().add(coordinate5);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(var.getName());
		nameLabel.setGraphics(graphicsName);
		
		HLAnnotation annotation = HlpngdefinitionFactory.eINSTANCE.createHLAnnotation();
		AnnotationGraphics labelPos = PnmlcoremodelFactory.eINSTANCE.createAnnotationGraphics();
		Coordinate offset = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		offset.setX(0);
		offset.setY(30);
		labelPos.setOffset(offset);
		annotation.setGraphics(labelPos);
		annotation.setText(var.getName());
		
		Variable variable = TermsFactory.eINSTANCE.createVariable();
		
		variable.setRefvariable(var);
		annotation.setStructure(variable);
		
		
		arc.setGraphics(graphics);
		arc.setId(id);
		arc.setName(nameLabel);
		arc.setSource(source);
		arc.setTarget(target);
		arc.setHlinscription(annotation);
		
		return arc;		
	}
	
	protected Arc createArc(String id,
			float xPosition, float yPosition, float xPosition1, float yPosition1, VariableDecl var, String name, float nameX,
			float nameY, Node source, Node target){
		
		Arc arc = AbstractginetFactory.eINSTANCE.createArc();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		ArcGraphics graphics = pnmlcoremodelFactory.createArcGraphics();

		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(xPosition);
		coordinate1.setY(yPosition);
		
		graphics.getPosition().add(coordinate1);
		
		Coordinate coordinate3 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate3.setX(xPosition);
		coordinate3.setY(yPosition);
		
		graphics.getPosition().add(coordinate3);
		
		Coordinate coordinate4 = pnmlcoremodelFactory.createCoordinate();

		coordinate4.setX(xPosition1);
		coordinate4.setY(yPosition1);
		
		graphics.getPosition().add(coordinate4);
		
		Coordinate coordinate5 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate5.setX(xPosition1);
		coordinate5.setY(yPosition1);
		
		graphics.getPosition().add(coordinate5);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		HLAnnotation annotation = HlpngdefinitionFactory.eINSTANCE.createHLAnnotation();
		AnnotationGraphics labelPos = PnmlcoremodelFactory.eINSTANCE.createAnnotationGraphics();
		Coordinate offset = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		offset.setX(0);
		offset.setY(30);
		labelPos.setOffset(offset);
		annotation.setGraphics(labelPos);
		annotation.setText(name);
		
		Variable variable = TermsFactory.eINSTANCE.createVariable();
		
		variable.setRefvariable(var);
		annotation.setStructure(variable);
		
		
		arc.setGraphics(graphics);
		arc.setId(id);
		arc.setName(nameLabel);
		arc.setSource(source);
		arc.setTarget(target);
		arc.setHlinscription(annotation);
		
		return arc;
		
	}
	
	public RefPlace createRefPlace(String id,
			int xPosition, int yPosition, String name, float nameX,
			float nameY, String parallelCardinality, PlaceNode node){
		
		RefPlace refPlace = AbstractginetFactory.eINSTANCE.createRefPlace();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(columns.get(xPosition));
		coordinate1.setY(rows.get(yPosition));

		graphics.setPosition(coordinate1);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		refPlace.setGraphics(graphics);
		refPlace.setName(nameLabel);
		refPlace.setId(id);
		refPlace.setParallelCardinality(parallelCardinality);
		refPlace.setRef(node);
		
		return refPlace;		
	}
	
	public RefPlace createRefPlace(String id,
			float xPosition, float yPosition, String name, float nameX,
			float nameY, String parallelCardinality, PlaceNode node){
		
		RefPlace refPlace = AbstractginetFactory.eINSTANCE.createRefPlace();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(xPosition);
		coordinate1.setY(yPosition);

		graphics.setPosition(coordinate1);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		refPlace.setGraphics(graphics);
		refPlace.setName(nameLabel);
		refPlace.setId(id);
		refPlace.setParallelCardinality(parallelCardinality);
		refPlace.setRef(node);
		
		return refPlace;		
	}
	
	public static Page createPage(String id,
			int xPosition, int yPosition, String name, float nameX,
			float nameY){
		
		Page page = AbstractginetFactory.eINSTANCE.createPage();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(columns.get(xPosition));
		coordinate1.setY(rows.get(yPosition));

		graphics.setPosition(coordinate1);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		page.setGraphics(graphics);
		page.setName(nameLabel);
		page.setId(id);
		
		return page;		
	}
	
	public static Page createPage(String id,
			float xPosition, float yPosition, String name, float nameX,
			float nameY){
		
		Page page = AbstractginetFactory.eINSTANCE.createPage();
		
		PnmlcoremodelFactory pnmlcoremodelFactory = PnmlcoremodelFactory.eINSTANCE;
		
		//graphics
		Coordinate coordinate = pnmlcoremodelFactory.createCoordinate();
		
		coordinate.setX(40);
		coordinate.setY(40);
		
		NodeGraphics graphics = pnmlcoremodelFactory.createNodeGraphics();

		graphics.setDimension(coordinate);
		
		Coordinate coordinate1 = pnmlcoremodelFactory.createCoordinate();

		coordinate1.setX(xPosition);
		coordinate1.setY(yPosition);

		graphics.setPosition(coordinate1);
		
		//Name		
		AnnotationGraphics graphicsName = pnmlcoremodelFactory
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = pnmlcoremodelFactory.createCoordinate();
		
		coordinate2.setX(nameX);
		coordinate2.setY(nameY);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		page.setGraphics(graphics);
		page.setName(nameLabel);
		page.setId(id);
		
		return page;		
	}

	public void createInteractionProtocol(InteractionPath ip, int pos,
			Page pageReturn, Place placeIn, Place placeOut,
			EList<Declaration> ginetDeclarations, Place termination,
			EList<BusinessMessage> bmmessages) {
		EList<Page> pages = new BasicEList<Page>();
		
		String pageName = "InteractionPath";
		
		if(ip.getName() != null && ip.getName().startsWith(pageName)){
			this.setName(pageReturn, ip.getName() + pos);
		}else if(ip.getName() == null){
			this.setName(pageReturn, pageName + pos);
		}else{
			this.setName(pageReturn, pageName+ip.getName() + pos);
		}

		this.setName(pageReturn, "InteractionPath" + pos);

		EList<BusinessMessage> messages = this.getBusinessMessages(bmmessages,
				ip);
		
		EList<InteractionProtocolElement> elements = new BasicEList<InteractionProtocolElement>();
		
		if(!ip.getElement().isEmpty()){
			elements.addAll(ip.getElement());
		}
		
		if(!messages.isEmpty()){
			elements.addAll(messages);
		}
		
		InteractionProtocolElement element = this.getBeginElement(elements);
		
		RefPlace refPlaceInit = this.createRefPlace("InRefPIP",
				80, (float) 114.5, "InRefPIP", -4,
				-9, "1", placeIn);
		
		Transition transitionInit = this.createTransition("InitTransition",
				160, (float) 114.5, "InitTransition", -9, -4, "1", "1", null);
		
		Arc arcRefITI = this.createArc("", this.getVarDec("gi"), -9, -19,
				refPlaceInit, transitionInit);
		
		pageReturn.getObject().add(refPlaceInit);
		pageReturn.getObject().add(transitionInit);
		pageReturn.getObject().add(arcRefITI);

		int i = 0;
		int k = 1;
		Transition transition = null;
		Place place2 = null;
		Place place = null;
		boolean isNotTermination = true;
		if(elements.isEmpty()){
			RefPlace refPlaceOut = this.createRefPlace("OutRefPIP",
					480, (float) 114.5, "OutRefPIP", -4,
					-9, "1", placeIn);
			
			Transition transitionOut = this.createTransition("OutTransition",
					400, (float) 114.5, "OutTransition", -9, -4, "1", "1", null);
			
			Arc arcRefOTI = this.createArc("", this.getVarDec("gi"), -9, -19,
					transitionOut, refPlaceOut);
			
			pageReturn.getObject().add(refPlaceOut);
			pageReturn.getObject().add(transitionOut);
			pageReturn.getObject().add(arcRefOTI);
		}else{
			while (element != null) {			

				Arc arc = null;
				Arc arc1 = null;

				Page page = null;

				if (element instanceof Termination) {
					if(element.getSuccessor() == null){
						RefPlace terminationRefPlace = this.createRefPlace(
								"Termination" + i, (240 + (320 * (i))), (float) 114.5,
								"Termination" + i, -4, -9, "1", termination);
						
						pageReturn.getObject().add(terminationRefPlace);
						
						if(transition != null){
							Arc arcT1 = this.createArc("", this.getVarDec("gi"), -9, -19,
									transition, terminationRefPlace);
							pageReturn.getObject().add(arcT1);
						}				
						isNotTermination = false;
					}else{
						RefPlace terminationRefPlace = this.createRefPlace(
								"Termination" + i, (240 + (320 * (i))), (float) 230,
								"Termination" + i, -4, -9, "1", termination);
						Arc arcT;
						if(transition != null){
							arcT = this.createArc("", this.getVarDec("gi"), -9, -19,
									transition, terminationRefPlace);
						}else{
							arcT = this.createArc("", this.getVarDec("gi"), -9, -19,
									transitionInit, terminationRefPlace);
						}
						pageReturn.getObject().add(terminationRefPlace);
						pageReturn.getObject().add(arcT);
						i--;
						k--;
					}
				} else {
					place = this.createPlace("InIP" + k, (240 + (320 * (i))),
							(float) 114.5, "InIP" + k, -4, -9,
							this.getVarDec("gi"), 6, 21, true, "1");
					if ((transition != null && element.getPredecessor() != null)) {
						if( !(element.getPredecessor() instanceof Termination)){
							arc = this.createArc("", this.getVarDec("gi"), -9, -19,
									transition, place);
						}
					}else if(element.getPredecessor() == null){
						arc = this.createArc("", this.getVarDec("gi"), -9, -19,
								transitionInit, place);
					}
			
					if (element.getSuccessor() != null
							&& !(element.getPredecessor() instanceof Termination)) {
						place2 = this.createPlace("OutIP" + k, (400 + (320 * (i))),
								(float) 114.5, "OutIP" + k, -4, -9,
								this.getVarDec("gi"), 6, 21, false, "1");
						transition = this.createTransition("IPTransition" + k,
								(480 + (320 * i)), (float) 114.5, "IPTransition"
										+ k, -9, -4, "1", "1", null);
						arc1 = this.createArc("", this.getVarDec("gi"), -9, -19,
								place2, transition);
					} else{
						
						place2 = this.createPlace("OutIP" + k, (400 + (320 * (i))),
								(float) 114.5, "OutIP" + k, -4, -9,
								this.getVarDec("gi"), 6, 21, false, "1");
	
						transition = null;
					}
					
					if (element instanceof BusinessMessage) {
						if(messages.contains(element)){
							page = this.getPageForElement(element, k,
									place, place2, ginetDeclarations,
									termination, bmmessages);
						}

					} else {
						page = this.getPageForElement(
								element,
								k, place, place2, ginetDeclarations,
								termination, bmmessages);
					}

					if (page != null) {

						NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
								.createNodeGraphics();

						Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
								.createCoordinate();

						coordinate.setX(40);
						coordinate.setY(40);

						graphics.setDimension(coordinate);

						Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
								.createCoordinate();

						coordinate1.setX((320 + (320 * i)));
						coordinate1.setY((float) 114.5);

						graphics.setPosition(coordinate1);

						page.setGraphics(graphics);

						pages.add(page);

						if (place != null) {
							pageReturn.getObject().add(place);
						}
						if (arc != null) {
							pageReturn.getObject().add(arc);
						}
						if (arc1 != null) {
							pageReturn.getObject().add(arc1);
						}
						if (place2 != null) {
							pageReturn.getObject().add(place2);
						}
						if (transition != null) {
							pageReturn.getObject().add(transition);
						}

					}
				}
				i++;
				k++;
				element = element.getSuccessor();
			}
			--i;
			if(isNotTermination){				
				RefPlace refPlaceOut = this.createRefPlace("OutRefPIP",
						(540 + (320 * i)), (float) 114.5, "OutRefPIP", -4,
						-9, "1", placeOut);
				
				Transition transitionOut = this.createTransition("OutTransition",
						(470 + (320 * i)), (float) 114.5, "OutTransition", -9, -4, "1", "1", null);
				
				Arc arcRefOTI = this.createArc("", this.getVarDec("gi"), -9, -19,
						transitionOut, refPlaceOut);
				Arc arcP2TOut = this.createArc("", this.getVarDec("gi"), -9, -19,
						place2, transitionOut);
				
				pageReturn.getObject().add(refPlaceOut);
				pageReturn.getObject().add(transitionOut);			
				pageReturn.getObject().add(arcRefOTI);
				pageReturn.getObject().add(arcP2TOut);
			}else{
				RefPlace refPlaceOut = this.createRefPlace("OutRefPIP",
						(470 + (320 * i)), (float) 114.5, "OutRefPIP", -4,
						-9, "1", placeOut);
				pageReturn.getObject().add(refPlaceOut);
			}
			
			pageReturn.getObject().addAll(pages);
		}

	}
	
	protected void setPosition(Place termination, float x, float y) {
		NodeGraphics graphics = PnmlcoremodelFactory.eINSTANCE
				.createNodeGraphics();

		Coordinate coordinate = PnmlcoremodelFactory.eINSTANCE
				.createCoordinate();

		coordinate.setX(40);
		coordinate.setY(40);

		graphics.setDimension(coordinate);

		Coordinate coordinate1 = PnmlcoremodelFactory.eINSTANCE
				.createCoordinate();

		coordinate1.setX(x);
		coordinate1.setY(y);
		
		graphics.setPosition(coordinate1);
		
		termination.setGraphics(graphics);		
	}
	
	protected void setName(Page page, String name) {
		//Name		
		AnnotationGraphics graphicsName = PnmlcoremodelFactory.eINSTANCE
				.createAnnotationGraphics();
		
		Name nameLabel = PnmlcoremodelFactory.eINSTANCE.createName();
		
		Coordinate coordinate2 = PnmlcoremodelFactory.eINSTANCE.createCoordinate();
		
		coordinate2.setX(-9);
		coordinate2.setY( -39);
		
		graphicsName.setOffset(coordinate2);
		
		nameLabel.setText(name);
		nameLabel.setGraphics(graphicsName);
		
		page.setName(nameLabel);
	}

	protected void fillVarDeclAndNameSort(EList<Declaration> ginetDeclarations){
		EList<org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Declaration> declarations = ginetDeclarations.get(0).getStructure().getDeclaration();
		for (org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Declaration declaration : declarations) {
			if(declaration instanceof NamedSort){
				this.namedSorts.add((NamedSort) declaration);
			}
			if(declaration instanceof VariableDecl){
				this.variableDecls.add((VariableDecl) declaration);
			}
		}
	}
	
	protected EList<VariableDecl> fillVarDecl(EList<Declaration> ginetDeclarations){
		EList<org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Declaration> declarations = ginetDeclarations.get(0).getStructure().getDeclaration();
		EList<VariableDecl> varDecl = new BasicEList<VariableDecl>();
		for (org.pnml.tools.epnk.pntypes.hlpngs.datatypes.terms.Declaration declaration : declarations) {
			if(declaration instanceof VariableDecl){
				varDecl.add((VariableDecl) declaration);
			}
		}
		
		return varDecl;
	}
	
	protected VariableDecl getVarDec(String name){
		VariableDecl varReturn = TermsFactory.eINSTANCE.createVariableDecl();
		
		for (VariableDecl var : this.variableDecls) {
			if(var.getName().equals(name)){
				varReturn.setId(var.getId());
				varReturn.setName(var.getName());
				MultiSetSort multiSet = (MultiSetSort) var.getSort().clone();
				UserSort userSort = (UserSort) ((MultiSetSort) var.getSort()).getBasis().clone();
				userSort.setName(((UserSort)((MultiSetSort) var.getSort()).getBasis()).getName());
				userSort.setDeclaration(((UserSort)((MultiSetSort) var.getSort()).getBasis()).getDeclaration());
				multiSet.setBasis(userSort);
				varReturn.setSort(multiSet);
				return varReturn;
			}
		}
		return null;
	}
	
	protected VariableDecl getVarDec(String name, EList<VariableDecl> variableDecls){
		VariableDecl varReturn = TermsFactory.eINSTANCE.createVariableDecl();
		
		for (VariableDecl var : variableDecls) {
			if(var.getName().equals(name)){
				varReturn.setId(var.getId());
				varReturn.setName(var.getName());
				MultiSetSort multiSet = (MultiSetSort) var.getSort().clone();
				UserSort userSort = (UserSort) ((MultiSetSort) var.getSort()).getBasis().clone();
				userSort.setName(((UserSort)((MultiSetSort) var.getSort()).getBasis()).getName());
				userSort.setDeclaration(((UserSort)((MultiSetSort) var.getSort()).getBasis()).getDeclaration());
				multiSet.setBasis(userSort);
				varReturn.setSort(multiSet);
				return varReturn;
			}
		}
		return null;
	}
	
	protected NamedSort getNamedSort(String name){
		NamedSort sortReturn = TermsFactory.eINSTANCE.createNamedSort();
		
		for (NamedSort n : this.namedSorts) {
			if(n.getName().equals(name)){
				sortReturn.setId(n.getId());
				sortReturn.setName(n.getName());
				Sort def = n.getDef().clone();
				sortReturn.setDef(def);
				return sortReturn;
			}
		}
		return null;
	}
	
	/**
	 * @param bMessages
	 * @param string
	 * @return
	 *
	 * @author Neri
	 */
	protected EList<BusinessMessage> getBusinessMessages(
			EList<BusinessMessage> bMessages, InteractionPath ip) {
		
		EList<BusinessMessage> messages = new BasicEList<BusinessMessage>();
		
		for (BusinessMessage businessMessage : bMessages) {
			if(businessMessage.getBmInteractionPath() != null
					&& businessMessage.getBmInteractionPath().equals(ip) && businessMessage.getBmInteractionPath().getInteractionPathBusinessMessages().contains(businessMessage)){
				messages.add(businessMessage);
			}
		}
		return messages;
	}
	
	protected EList<BusinessMessage> getBusinessMessagesForInteractionProtocol(
			EList<BusinessMessage> bMessages) {
		
		EList<BusinessMessage> messages = new BasicEList<BusinessMessage>();
		
		for (BusinessMessage businessMessage : bMessages) {
			if(businessMessage.getBmInteractionPath() == null){
				messages.add(businessMessage);
			}
		}
		return messages;
	}
	
	protected EList<InteractionProtocolElement> orderListWithTerminationLast(EList<InteractionProtocolElement> list){
		EList<InteractionProtocolElement> elements = new BasicEList<InteractionProtocolElement>();
		EList<InteractionProtocolElement> terminates = new BasicEList<InteractionProtocolElement>();
		for (InteractionProtocolElement element : list) {
			if(element instanceof Termination){
				terminates.add(element);
			}else{
				elements.add(element);
			}
		}
		
		elements.addAll(terminates);
		
		return elements;
	}
	
	protected boolean hasTerminationExplicit(
			EList<InteractionProtocolElement> elements) {
		
		for (InteractionProtocolElement element : elements) {
			if(element.getSuccessor() == null){
				if(element instanceof Termination){
					return true;
				}
			}
		}
		return false;
	}

	protected InteractionProtocolElement getBeginElement(
			EList<InteractionProtocolElement> elements) {

		for (InteractionProtocolElement element : elements) {
			if(element.getPredecessor() == null){
				return element;
			}
		}
		
		return null;
	}
	
	protected void setPageName(InteractionProtocolElement element){	
		
		if(element.getName() != null && element.getName().toUpperCase().startsWith(this.abstractPage.getName().getText())){
			this.abstractPage.getName().setText(element.getName() + this.pos);
		}else if(element.getName() == null){
			this.abstractPage.getName().setText(this.abstractPage.getName().getText()+ this.pos);
		}else{
			this.abstractPage.getName().setText(this.abstractPage.getName().getText()+element.getName() + this.pos);
		}
	}
	
	public Page getPageForElement(InteractionProtocolElement element, int count, Place placeIn, Place placeOut, EList<Declaration> ginetDeclarations, Place termination, EList<BusinessMessage> messages){
		return PageGiNetCreator.createAbstractPage(element, count, placeIn, placeOut, ginetDeclarations, termination, messages);
	}
	
	public void createPageStructure(InteractionProtocolElement element, Place placeIn, Place placeOut, EList<Declaration> ginetDeclarations, Place termination, EList<BusinessMessage> messages){
		
	}
}
